package com.jianganming.nio.file;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class FileServer {
    private ServerSocketChannel serverSocketChannel;
    private Selector selector;
    private FileOutputStream out;
    private FileChannel fileChannel;
    private ByteBuffer buffer = ByteBuffer.allocate(1024*1024);

    public FileServer(){
        try {
            serverSocketChannel = ServerSocketChannel.open();

            serverSocketChannel.socket().bind(new InetSocketAddress(9999));
            //设置为非阻塞
            serverSocketChannel.configureBlocking(false);

            selector = Selector.open();
            //注册到selector
            serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);

            out = new FileOutputStream("/Users/jianganming/Downloads/RabbitMQ2.pdf");

            fileChannel = out.getChannel();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public void listen()throws Exception{
        while (true){
            //服务器等待了1秒,如果没有客户端连接就轮训，直到客户端连接成功
            if(selector.select()>0){
                //获取选择器的key
                Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

                while (iterator.hasNext()){

                    SelectionKey key = iterator.next();
                    //如果获得连接
                    if(key.isAcceptable()){
                        //注册
                        SocketChannel socketChannel = registerSocketChannel();
                        System.out.println(socketChannel.getRemoteAddress()+": 上线");
                    }
                    //如果是可读状态
                    if(key.isReadable()){
                        //读取数据
                        readData(key);
                    }

                    iterator.remove();
                }
            }else {
                System.out.println("等待...");
            }


        }
    }

    private SocketChannel registerSocketChannel()throws Exception {
        SocketChannel socketChannel = serverSocketChannel.accept();

        socketChannel.configureBlocking(false);
        //注册为可读的通道
        socketChannel.register(selector,SelectionKey.OP_READ,ByteBuffer.allocate(1024));

        return socketChannel;
    }

    private void readData(SelectionKey key)throws Exception {
            //buffer.clear();
            SocketChannel socketChannel = (SocketChannel) key.channel();
            int num = 0;
            try {
                while ((num = socketChannel.read(buffer)) > 0) {
                    buffer.flip();
                    // 写入文件
                    fileChannel.write(buffer);
                    buffer.clear();
                }
            } catch (IOException e) {
                key.cancel();
                e.printStackTrace();
                return;
            }
            // 调用close为-1 到达末尾
            if (num == -1) {
                fileChannel.close();
                System.out.println("上传完毕");
                buffer.clear();
                socketChannel.write(buffer);
                key.cancel();
            }

        }


    public static void main(String[] args)throws Exception {
        new FileServer().listen();
    }
}
